home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / ptrmgr.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  10KB  |  585 lines

  1. /* --------------------------------- ptrmgr.c ------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* Pointing devices manager.
  8. */
  9.  
  10. #include "fly.h"
  11.  
  12.  
  13. LOCAL_FUNC void    NEAR get_btns (POINTER *p, char *options);
  14.  
  15. extern int FAR
  16. pointers_init (void)
  17. {return (0);}
  18.  
  19. extern void FAR
  20. pointers_term (void)
  21. {}
  22.  
  23. static int def_opt[NOPTS] = {
  24.     1,        /* +ve x */
  25.     0,        /* x axis is channel 0 */
  26.     1,        /* +ve y */
  27.     1        /* y axis is channel 1 */
  28. };
  29.  
  30. extern POINTER * FAR
  31. pointer_select (char *name)
  32. {
  33.     int            l, n;
  34.     char            *options;
  35.     int            opt[NOPTS];
  36.     POINTER            *ptr;
  37.     struct PtrDriver    NEAR* FAR* p;
  38.  
  39.     memcpy (opt, def_opt, sizeof (opt));
  40.  
  41.     if (!name) {
  42.         p = PtrDrivers;                /* use default */
  43.         options = "";
  44.         goto ret;
  45.     }
  46.  
  47.     options = strchr (name, ':');
  48.     if (options) {        /* ":+x+y" */
  49.         n = options - name;            /* name length */
  50.         ++options;
  51.         l = strlen (options);            /* options length */
  52.  
  53.         if (l >= 1) {
  54.             if (options[0] == '-')        /* x direction */
  55.                 opt[0] = -1;
  56.             else if (options[0] == '+')
  57.                 opt[0] = 1;
  58.             else
  59.                 return (0);
  60.         }
  61.         if (l >= 2) {
  62.             if (options[1] == 'x')        /* x select */
  63.                 opt[1] = 0;
  64.             else if (options[1] == 'y')
  65.                 opt[1] = 1;
  66.             else
  67.                 return (0);
  68.         }
  69.  
  70.         if (l >= 3) {
  71.             if (options[2] == '-')        /* y direction */
  72.                 opt[2] = -1;
  73.             else if (options[2] == '+')
  74.                 opt[2] = 1;
  75.             else
  76.                 return (0);
  77.         }
  78.         if (l >= 4) {
  79.             if (options[3] == 'x')        /* y select */
  80.                 opt[3] = 0;
  81.             else if (options[3] == 'y')
  82.                 opt[3] = 1;
  83.             else
  84.                 return (0);
  85.             if (opt[1] == opt[3])        /* exclusive */
  86.                 return (0);
  87.         }
  88.     } else
  89.         n = strlen (name);
  90.  
  91.     for (p = PtrDrivers; *p; ++p) {
  92.         if (!strnicmp ((*p)->name, name, n) && !(*p)->name[n])
  93.             break;
  94.     }
  95. ret:
  96.     if (!*p)
  97.         return (0);
  98.  
  99.     if (!NEW (ptr))
  100.         return (0);
  101.  
  102.     ptr->control = *p;
  103.     ptr->name    = (*p)->name;
  104.     memcpy (ptr->opt, opt, sizeof (ptr->opt));
  105.  
  106.     get_btns (ptr, options);
  107.  
  108.     if (ptr->control->Init (ptr, options))
  109.         DEL0 (ptr);
  110.  
  111.     return (ptr);
  112. }
  113.  
  114. extern POINTER * FAR
  115. pointer_release (POINTER *ptr)
  116. {
  117.     ptr->control->Term (ptr);
  118.     DEL (ptr);
  119.     return (0);
  120. }
  121.  
  122. extern void FAR
  123. std_key (POINTER *p, int key)
  124. {
  125.     int    i;
  126.  
  127.     switch (key) {
  128.     case KF_POWER_AB:
  129.         if (p->l[3] < 75)
  130.             p->l[3] = 75;        /* full power first */
  131.         else {
  132.             p->l[3] += 5;
  133.             if (p->l[3] > 100)
  134.                 p->l[3] = 100;
  135.         }
  136.         break;
  137.  
  138.     case KF_POWER_UP:
  139.         i = (p->l[3] > 75) ? 100 : 75;
  140.         p->l[3] += 5;
  141.         if (p->l[3] > i)
  142.             p->l[3] = i;
  143.         break;
  144.  
  145.     case KF_POWER_DOWN:
  146.         p->l[3] -= 5;
  147.         if (p->l[3] < 0)
  148.             p->l[3] = 0;
  149.         break;
  150.  
  151.     case KF_POWER_0:
  152.         p->l[3] = 0;
  153.         break;
  154.  
  155.     case KF_POWER_100:
  156.         p->l[3] = 75;
  157.         break;
  158.  
  159.     case KF_LEVEL:
  160.         ++p->b[0];
  161.         break;
  162.  
  163.     case KF_ORIGIN:
  164.         ++p->b[1];
  165.         break;
  166.  
  167.     case KF_FIRE:
  168.         ++p->b[2];
  169.         break;
  170.  
  171.     case KF_RESET_ROLL:
  172.         ++p->b[4];
  173.         break;
  174.  
  175.     case KF_STABLE:
  176.         ++p->b[3];
  177.         break;
  178.  
  179.     case KF_FRUDLEFT:        /* rudder left */
  180.         p->l[2] += 10;
  181.         if (p->l[2] > 100)
  182.             p->l[2] = 100;
  183.         break;
  184.     case KF_FRUDRITE:        /* rudder right */
  185.         p->l[2] -= 10;
  186.         if (p->l[2] < -100)
  187.             p->l[2] = -100;
  188.         break;
  189.     case KF_FRUDCNTR:        /* rudder center */
  190.         p->l[2] = 0;
  191.         break;
  192.  
  193.     case ']':            /* flaps: more */
  194.         p->l[6] += 10;
  195.         if (p->l[6] > 100)
  196.             p->l[6] = 100;
  197.         break;
  198.     case '[':            /* flaps: less */
  199.         p->l[6] -= 10;
  200.         if (p->l[6] < 0)
  201.             p->l[6] = 0;
  202.         break;
  203.  
  204.     case '}':            /* spoilers: more */
  205.         p->l[7] += 10;
  206.         if (p->l[7] > 100)
  207.             p->l[7] = 100;
  208.         break;
  209.     case '{':            /* spoilers: less */
  210.         p->l[7] -= 10;
  211.         if (p->l[7] < 0)
  212.             p->l[7] = 0;
  213.         break;
  214.  
  215.     case ')':            /* wheel brakes: more */
  216.         p->l[9] += 10;
  217.         if (p->l[9] > 100)
  218.             p->l[9] = 100;
  219.         break;
  220.     case '(':            /* wheel brakes: less */
  221.         p->l[9] -= 10;
  222.         if (p->l[9] < 0)
  223.             p->l[9] = 0;
  224.         break;
  225.  
  226.     case '>':            /* speed brakes: more */
  227.         p->l[8] += 25;
  228.         if (p->l[8] > 100)
  229.             p->l[8] = 100;
  230.         break;
  231.     case '<':            /* speed brakes: less */
  232.         p->l[8] -= 25;
  233.         if (p->l[8] < 0)
  234.             p->l[8] = 0;
  235.         break;
  236.  
  237.     case '+':            /* speed brakes on/off */
  238.         if (p->l[8])
  239.             p->l[8] = 0;
  240.         else
  241.             p->l[8] = 100;
  242.         break;
  243.  
  244.     case 'b':            /* wheels brakes on/off */
  245.         if (p->l[9])
  246.             p->l[9] = 0;
  247.         else
  248.             p->l[9] = 100;
  249.         break;
  250.  
  251.     case 'g':
  252.         ++p->b[5];        /* landing gear up/down */
  253.         break;
  254.  
  255.     case ' ':
  256.         ++p->b[6];        /* release radar lock */
  257.         break;
  258.  
  259. /* Ctl Arrows used for trim.
  260. */
  261.     case KF_ZRIGHT:            /* trim: right */
  262.         ++p->l[4];
  263.         if (p->l[4] > 100)
  264.             p->l[4] = 100;
  265.         break;
  266.     case KF_ZLEFT:            /* trim: left */
  267.         --p->l[4];
  268.         if (p->l[4] < -100)
  269.             p->l[4] = -100;
  270.         break;
  271.     case KF_ZUP:            /* trim: nose down */
  272.         --p->l[5];
  273.         if (p->l[5] < -100)
  274.             p->l[5] = -100;
  275.         break;
  276.     case KF_ZDOWN:            /* trim: nose up */
  277.         ++p->l[5];
  278.         if (p->l[5] > 100)
  279.             p->l[5] = 100;
  280.         break;
  281.     case '\\':            /* trim: reset */
  282.         p->l[4] = p->l[5] = 0;
  283.         break;
  284.     }
  285. }
  286.  
  287. /* Select Pointing Device
  288. */
  289.  
  290. extern int FAR
  291. menu_ptrs (void)
  292. {
  293.     MENU    *MenuPtr;
  294.     int    sel, i, nEntries, EntrySize;
  295.     char    *oldptr, newptr[256], *p;
  296.     POINTER    *ptr;
  297.  
  298.     for (nEntries = 0; PtrDrivers[nEntries]; ++nEntries)
  299.         ;
  300.         ;
  301.     EntrySize = 20;
  302.  
  303.     if (!(MenuPtr = (MENU *) memory_calloc (nEntries+1,
  304.                             sizeof (*MenuPtr))))
  305.         return (1);
  306.  
  307.     sel = MENU_FAILED;
  308.     for (i = 0; i < nEntries; ++i)
  309.         if (!(MenuPtr[i].text = (char *) memory_alloc (EntrySize)))
  310.             goto ret;
  311.  
  312.     oldptr = st.ptrname;
  313.     sel = 0;
  314.     for (i = 0; i < nEntries; ++i) {
  315.         MenuPtr[i].letter = (Uchar)menuch[i];
  316.         strcpy (MenuPtr[i].text, PtrDrivers[i]->name);
  317.         if (!stricmp (PtrDrivers[i]->name, oldptr))
  318.             sel = i;
  319.     }
  320.  
  321.     sel = menu_open (MenuPtr, sel);
  322.  
  323.     oldptr = st.ptrname;
  324.  
  325.     switch (sel) {
  326.     case MENU_ABORTED:
  327.     case MENU_FAILED:
  328.         break;
  329.     default:
  330.         strcpy (newptr, PtrDrivers[sel]->name);
  331.         strcat (newptr, ":");
  332.         i = strlen (newptr);
  333.         if (NULL != (p = strchr (oldptr, ':')))
  334.             strcpy (newptr+i, p+1);
  335.         edit_str ("pointer options:", newptr + i, sizeof (newptr) - i);
  336.  
  337.         sim_set ();
  338.         if (T(ptr = CV->pointer))
  339.             CV->pointer = pointer_release (ptr);
  340.         for (;;) {
  341.             if (T(ptr = pointer_select (newptr))) {
  342.                 CV->pointer = ptr;
  343.                 st.ptrname = STRfree (st.ptrname);
  344.                 st.ptrname = STRdup (newptr);
  345.                 break;
  346.             }
  347.             MsgEPrintf (-100, "pointer init failed");
  348.             if (T(ptr = pointer_select (oldptr))) {
  349.                 CV->pointer = ptr;
  350.                 break;
  351.             }
  352.             MsgEPrintf (-100, "old pointer init failed");
  353.             if (oldptr) {
  354.                 if (T(ptr = pointer_select (NULL))) {
  355.                     CV->pointer = ptr;
  356.                     st.ptrname = STRfree (st.ptrname);
  357.                     st.ptrname = STRdup (ptr->name);
  358.                     break;
  359.                 }
  360.             }
  361.             LogPrintf ("default pointer init failed\n");
  362.             die ();
  363.         }
  364.         sim_reset ();
  365.         break;
  366.     }
  367.  
  368. ret:
  369.     for (i = 0; i < nEntries; ++i)
  370.         if (MenuPtr[i].text)
  371.             memory_free (MenuPtr[i].text, EntrySize);
  372.  
  373.     MenuPtr = memory_cfree (MenuPtr, nEntries+1, sizeof (*MenuPtr));
  374.  
  375.     if (MENU_FAILED == sel)
  376.         return (1);
  377.  
  378.     menu_close ();
  379.     return (0);
  380. }
  381.  
  382.  
  383. /* From here on: buttons stuff.
  384. */
  385.  
  386. #define BTN_POSITION    0x0001
  387. #define BTN_DEBOUNCE    0x0080
  388.  
  389. LOCAL_FUNC void NEAR
  390. get_btn (POINTER *p, char *options, char *opt, Ushort mode)
  391. {
  392.     char    *s;
  393.     int    n;
  394.     int    prev;
  395.     int    quit;
  396.  
  397.     if (F(s = get_arg (options, opt)))
  398.         return;
  399.  
  400.     for (prev = 0, quit = 0; !quit;) {
  401.         if ('-' == (n = *s++)) {
  402.             if ((n = opt36 (*s++)) < 0) {
  403.                 quit = 1;
  404.                 n = rangeof (p->btn) - 1;
  405.             }
  406.             while (prev <= n)
  407.                 p->btn[prev++] |= mode;
  408.         } else if ((n = opt36 (n)) >= 0)
  409.             p->btn[n] |= mode;
  410.         else
  411.             quit = 1;
  412.         prev = n;
  413.     }
  414. }
  415.  
  416. /* read button debounce definition.
  417. */
  418. LOCAL_FUNC void NEAR
  419. get_btns (POINTER *p, char *options)
  420. {
  421.     int    n;
  422.  
  423.     for (n = 0; n < rangeof (p->btn); ++n)
  424.         p->btn[n] = 0;
  425.  
  426.     get_btn (p, options, "d=", BTN_DEBOUNCE);
  427.     get_btn (p, options, "r=", K_RLS);
  428.  
  429.     get_btn (p, options, "a=", K_ALT);
  430.     get_btn (p, options, "c=", K_CTRL);
  431.     get_btn (p, options, "p=", K_SPECIAL);
  432.     get_btn (p, options, "s=", K_SHIFT);
  433.  
  434. /* remember that debounce and release have a negative logic.
  435. */
  436.     for (n = 0; n < rangeof (p->btn); ++n)
  437.         p->btn[n] ^= (BTN_DEBOUNCE | K_RLS);
  438. }
  439.  
  440. /* handle a button press with debouncing.
  441. */
  442. extern void FAR
  443. do_btn (POINTER *p, int button, int state)
  444. {
  445.     Ushort    cmd[1];
  446.  
  447.     if (state)
  448.         state = BTN_POSITION;
  449.  
  450.     if ((BTN_POSITION & p->btn[button]) != (Ushort)state)    /* toggle */
  451.         p->btn[button] ^= BTN_POSITION;
  452.     else if (BTN_DEBOUNCE & p->btn[button])
  453.         return;                    /* debounce */
  454.  
  455. /* do not interfere with user keystrokes.
  456. */
  457.     if (st.flags & SF_INTERACTIVE)
  458.         return;
  459.  
  460.     if (state)
  461.         cmd[0] = 0;
  462.     else if (K_RLS & p->btn[button])
  463.         cmd[0] = K_RLS;
  464.     else
  465.         return;
  466.  
  467.     cmd[0] |= K_BTN | (st.btnmode & p->btn[button] & K_MODES)
  468.                             | menuch[button];
  469.     mac_interpret (cmd, rangeof (cmd));
  470. }
  471.  
  472. extern void FAR
  473. do_btns (POINTER *p, char *btn, int size)
  474. {
  475.     int    i;
  476.  
  477. /* button releases
  478. */
  479.     for (i = 0; i < size; ++i)
  480.         if (!btn[i])
  481.             do_btn (p, i, 0);
  482.     for (; i < rangeof (p->btn); ++i)
  483.         if (!(p->btn[i] & BTN_POSITION))
  484.             do_btn (p, i, 0);
  485.  
  486. /* button presses
  487. */
  488.     for (i = 0; i < size; ++i)
  489.         if (btn[i])
  490.             do_btn (p, i, 1);
  491.     for (; i < rangeof (p->btn); ++i)
  492.         if (p->btn[i] & BTN_POSITION)
  493.             do_btn (p, i, 1);
  494. }
  495.  
  496. /* Set buttons mode.
  497. */
  498.  
  499. static MENU FAR MenuBtn[] = {
  500.     {'0', "off"},
  501.     {'1', "on"},
  502.     {'2', "toggle"},
  503.     {'a', "Alt"},        /*  3 */
  504.     {'c', "Ctrl"},        /*  4 */
  505.     {'s', "Shift"},        /*  5 */
  506.     {'p', "sPecial"},    /*  6 */
  507.     {'d', "Debounce"},    /*  7 */
  508.     {'r', "Release"},    /*  8 */
  509.     {'x', "Clear"},        /*  9 */
  510.     {'*', "Cancel"},    /* 10 */
  511. {'\0', 0}};
  512.  
  513. extern int FAR
  514. menu_btn (void)
  515. {
  516.     int    sel, quit, ch;
  517.     Ushort    i;
  518.     int    j;
  519.     HMSG    *m;
  520.     POINTER *p;
  521.  
  522.     if (F(p = CC->pointer))
  523.         MsgWPrintf (50, "No pointer!");
  524.  
  525.     m = MsgEPrintf (0, "enter button name:");
  526.     do {
  527.         ch = mgetch ();
  528.         j = opt36 (ch);
  529.     } while (j < 0);
  530.     msg_del (m);
  531.  
  532.     m = MsgEPrintf (0, "defining button %c", ch);
  533.     i = p ? p->btn[j] : 0;
  534.  
  535.     SetOption (0, 2);        /* default mode: toggle */
  536.     sel = 2;
  537.     for (quit = 0; !quit;) {
  538.         sel = menu_open (MenuBtn, sel);
  539.         switch (sel) {
  540.         case MENU_ABORTED:
  541.         default:
  542.             quit = 1;
  543.             break;
  544.         case 0:
  545.         case 1:
  546.         case 2:
  547.             SetOption (0, sel);
  548.             break;
  549.         case 3:
  550.             SetOption (&i, K_ALT);
  551.             break;
  552.         case 4:
  553.             SetOption (&i, K_CTRL);
  554.             break;
  555.         case 5:
  556.             SetOption (&i, K_SHIFT);
  557.             break;
  558.         case 6:
  559.             SetOption (&i, K_SPECIAL);
  560.             break;
  561.         case 7:
  562.             SetOption (&i, K_RLS);
  563.             break;
  564.         case 8:
  565.             SetOption (&i, BTN_DEBOUNCE);
  566.             break;
  567.         case 9:
  568.             i = 0;
  569.             SetOption (0, 1);
  570.             break;
  571.         case 10:
  572.             i = p ? p->btn[j] : 0;
  573.             quit = 1;
  574.             break;
  575.         }
  576.         if (MENU_FAILED != sel)
  577.             menu_close ();
  578.     }
  579.     if (p)
  580.         p->btn[j] = i;
  581.     msg_del (m);
  582.     return (0);
  583. }
  584. #undef NO_DEBOUNCE
  585.